<?php
// @formatter:off
/**
 * @file WCRule.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-05-27 04:56:35 +0000 (Mon, 27 May 2013) $
 *
 * $Id: WCRule.php 67 2013-05-27 04:56:35Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0-BETA1/includes/representations/WCRule.php $
 */
// @formatter:on

require_once "{$wcPaths["includes-directory"]}/WCRuleAction.php";
require_once "{$wcPaths["includes-directory"]}/search/WCSearch.php";

/**
 * @class WCRule
 */
class WCRule extends WCGTableRepresentation implements WCSearchIndexable, WCPreviews {
	public static $PreviewsSeparator = "|";
	public static $PreviewsMaxLength = 640;

	protected $_PropertiesBoolean = array(
		"conflict",
		"enabled",
		"indexed"
	);
	protected $_PropertiesPrefix = "rul_";
	protected $_PropertiesTable = "rules";

	/**
	 * @var WCRuleAction[int]
	 */
	protected $_actions = array();

	public function __destruct() {
	}
	//
	// Public methods
	/**
	 * @return WCRuleAction[int]
	 */
	public function actions() {
		$this->loadActions();
		return $this->_actions;
	}
	public function actionsIds() {
		$this->loadActions();
		return $this->ok() ? array_keys($this->_actions) : array();
	}
	public function count() {
		$out = array();

		global $wcRuleHooks;
		foreach($wcRuleHooks as $id => $value) {
			$out[$id] = 0;
		}

		$this->loadActions();
		foreach($this->actions() as $action) {
			$out[$action->type()]++;
		}

		return $out;
	}
	public function generatePreviews() {
		$out = false;

		global $wcPageCache;
		$wcPageCache->invalidateByRule($this);

		$previewsFull = array();
		foreach($this->actions() as $action) {
			$previewsFull = array_merge($previewsFull, $action->previews());
		}

		$previewsCount = count($previewsFull);

		if($previewsCount > 0) {
			$previewsCount = $previewsCount > 10 ? 10 : $previewsCount;
			$previews = array();

			if($previewsCount > 1) {
				foreach(array_rand($previewsFull,$previewsCount) as $id) {
					$previews[] = $previewsFull[$id];
				}
			} else {
				$previews[] = $previewsFull[0];
			}

			$count = count($previews);
			if($count && $count == $previewsCount) {
				$this->previews = implode(self::$PreviewsSeparator, $previews);
				$out = true;
			}
		}

		return $out;
	}
	public function hasPreview() {
		return $this->hasPreviews();
	}
	public function hasPreviews() {
		return false;
	}
	public function indexed($value = null) {
		if($value !== null) {
			$this->indexed = $value;
			foreach($this->actions() as $action) {
				$action->indexed($value);
			}
		}

		if($this->indexed) {
			foreach($this->actions() as $action) {
				if(!$action->indexed()) {
					$this->indexed = false;
					break;
				}
			}
		}

		return $this->indexed;
	}
	/**
	 * Loads a specific rule.
	 *
	 * @param int $rule Rule id to be loaded.
	 * @param WCGroup $group Group where the rule belongs.
	 */
	public function load($id, WCGroup &$group) {
		parent::load($id, $group);

		$this->_info["rul_previews"] = $this->_info["rul_previews"] ? $this->_info["rul_previews"] : false;

		return $this->ok();
	}
	public function loadByName($name, WCGroup &$group) {
		$out = false;

		$stmt = null;
		$stmtId = __CLASS__."::".__FUNCTION__;
		IF($this->_db->has($stmtId)) {
			$stmt = $this->_db->get($stmtId);
		} else {
			$query = "select  *\n";
			$query .= "from    {$this->_dbprefix}ruless\n";
			$query .= "where   rul_group = :group\n";
			$query .= " and    rul_name  = :name\n";

			$stmt = $this->_db->prepare($stmtId, $query);
		}

		$params = array(
			":group" => $group->id,
			":name" => $name
		);

		if($stmt->execute($params)) {
			$row = $stmt->fetch();
			$out = $this->load($row["rul_id"], $group);
		}

		return $out;
	}
	public function name() {
		return $this->name;
	}
	public function preview() {
		if($this->previews) {
			$list = $this->previews();
			return array_shift($list);
		} else {
			return "";
		}
	}
	public function previews() {
		if($this->previews) {
			return explode(self::$PreviewsSeparator, $this->previews);
		} else {
			return array();
		}
	}
	public function reload() {
		$this->_actions = array();
		return parent::reload();
	}
	public function remove() {
		foreach($this->actions() as $action) {
			$action->remove();
		}
		return parent::remove();
	}
	public function run($noConflics = false) {
		$informs = array();

		if($this->enabled) {
			$this->count = count($this->actionsIds());
			foreach($this->actions() as $action) {
				$action->setIgnoreConfics(!$noConflics);
				$informs[] = $action->run();
			}
		}

		return $informs;
	}
	public function words() {
		$out = WCSearchFactory::StringToPatterns($this->name);

		foreach($this->actions() as $action) {
			$out = array_merge($out, $action->words());
		}

		return $out;
	}
	//
	// Protected methods
	protected function loadActions() {
		if($this->ok() && !count($this->_actions)) {
			$this->_actions = array();

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__;
			IF($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "select  *\n";
				$query .= "from    {$this->_dbprefix}rule_actions\n";
				$query .= "where   rel_ra_rule = :rule\n";
				$query .= "order by rel_ra_type asc\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			if($stmt->execute(array(":rule" => $this->id))) {
				foreach($stmt->fetchAll() as $row) {
					$action = WCRulesHolder::ActionFactory($row["rel_ra_type"], $this->id, $row["rel_ra_action"], $this->_group);
					if($action->ok()) {
						$this->_actions[$action->id()] = $action;
					}
				}
			}
		}
	}
	//
	// Public Class Methods
	public static function Sort($a, $b) {
		return self::NameSort($a, $b);
	}
	public static function IdSort($a, $b) {
		return $a->id > $b->id;
	}
	public static function NameSort($a, $b) {
		return $a->name > $b->name;
	}
}
?>